package com.bysc.commentservice.controller;


import com.bysc.baseservice.handler.BaiYunException;
import com.bysc.commentservice.entity.CommentPost;
import com.bysc.commentservice.entity.vo.CommentQueryVo;
import com.bysc.commentservice.entity.vo.PostFormVo;
import com.bysc.commentservice.service.CommentPostService;
import com.bysc.commonutils.ResultCode;
import com.bysc.commonutils.Results;
import com.bysc.commonutils.constant.MessageConstant;
import com.bysc.commonutils.utils.JwtUtils;
import com.bysc.commonutils.vo.PageResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author kkk
 * @since 2024-06-15
 */
@Api(tags = "帖子管理")
@RestController
@RequestMapping("/commentservice/comment-post")
public class CommentPostController {
    @Autowired
    private CommentPostService commentPostService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;

    @ApiOperation(value = "根据Token新增帖子")
    @PostMapping("addPostByToken")
    public Results addPostParentByPostIdAndToken(@ApiParam(name = "postVo", value = "帖子信息", required = true)
                                                 @RequestBody PostFormVo postFormVo, HttpServletRequest httpRequest) {
        try {
            String userId = JwtUtils.getMemberIdByJwtToken(httpRequest);
            CommentPost commentPost = commentPostService.addPostByToken(postFormVo, userId);
            return Results.ok().data("id", commentPost.getId()).message(MessageConstant.ADD_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (Exception e) {
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.ADD_POST_FAIL);
        }

    }

    @ApiOperation(value = "根据postId修改帖子")
    @PutMapping("updatePostByPostId/{id}")
    public Results updatePostByPostId(@ApiParam(name = "id", value = "帖子id", required = true)
                                      @PathVariable Object id, @ApiParam(name = "postVo", value = "帖子信息", required = true)
                                      @RequestBody PostFormVo postFormVo) {
        try {
            commentPostService.updatePost(postFormVo, id);
            return Results.ok().message(MessageConstant.EDIT_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (Exception e) {
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.EDIT_POST_FAIL);
        }
    }

    @ApiOperation(value = "根据postId查询帖子基础信息")
    @GetMapping("getPostByPostId/{id}")
    public Results getPostByPostId(@ApiParam(name = "id", value = "帖子id", required = true)
                                   @PathVariable Object id) {
        try {
            CommentPost commentPost = commentPostService.getPostByPostId(id);
            PostFormVo postFormVo = new PostFormVo();
            BeanUtils.copyProperties(commentPost, postFormVo);
            return Results.ok().data("post", postFormVo).message(MessageConstant.QUERY_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (BeansException e) {
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.QUERY_POST_FAIL);
        }
    }

    @ApiOperation(value = "根据(token和)postId查询帖子详情")
    @GetMapping("getPostInfoByTokenAndPostId/{id}")
    public Results getPostInfoByTokenAndPostId(@ApiParam(name = "id", value = "帖子id", required = true)
                                               @PathVariable Object id, HttpServletRequest request) {
        try {
            //TODO 新增缓存层优化查询
            String userId = JwtUtils.getMemberIdByJwtToken(request);
            CommentPost commentPost = commentPostService.getPostInfoByTokenAndPostId(userId, id);
            return Results.ok().data("post", commentPost).message(MessageConstant.QUERY_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (Exception e) {
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.QUERY_POST_FAIL);
        }
    }

    @ApiOperation(value = "根据postId删除帖子")
    @DeleteMapping("deletePostByPostId/{id}")
    public Results deletePostByPostId(@ApiParam(name = "id", value = "帖子id", required = true) @PathVariable Object id) {
        try {
            CommentPost commentPost = commentPostService.deletePost(id);
            return Results.ok().data("id", commentPost.getId()).message(MessageConstant.DELETE_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (Exception e) {
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.DELETE_POST_FAIL);
        }
    }

    @ApiOperation(value = "（带条件）分页查询最新帖子")
    @PostMapping("getPostListByCommentQueryVoAndTokenOrderByCreatTime/{page}/{limit}")
    public Results getPostListByCommentQueryVoAndTokenOrderByCreatTime(@ApiParam(name = "page", value = "查询页数", required = true)
                                                                       @PathVariable Integer page, @ApiParam(name = "limit", value = "查询数量", required = true)
                                                                       @PathVariable Integer limit, @ApiParam(name = "queryVo", value = "查询条件", required = false) @RequestBody CommentQueryVo queryVo, HttpServletRequest request) {
        try {
            String userId = JwtUtils.getMemberIdByJwtToken(request);
            PageResult PageResult = commentPostService.getPostListByCommentQueryVoAndTokenOrderByCreatTime(userId, page, limit, queryVo);
            return Results.ok().data("page", PageResult).message(MessageConstant.QUERY_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (Exception e) {
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.QUERY_POST_FAIL);
        }
    }

    @ApiOperation(value = "分页查询点赞过最新帖子")
    @PostMapping("getLikedPostListByToken/{page}/{limit}")
    public Results getLikedPostListByToken(@ApiParam(name = "page", value = "查询页数", required = true)
                                           @PathVariable Integer page, @ApiParam(name = "limit", value = "查询数量", required = true)
                                           @PathVariable Integer limit, HttpServletRequest request) {
        try {
            String userId = JwtUtils.getMemberIdByJwtToken(request);
            PageResult PageResult = commentPostService.getLikedPostListByToken(userId, page, limit);
            return Results.ok().data("page", PageResult).message(MessageConstant.QUERY_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (Exception e) {
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.QUERY_POST_FAIL);
        }
    }

    @ApiOperation(value = "分页查询收藏过最新帖子")
    @PostMapping("getCollectedPostListByToken/{page}/{limit}")
    public Results getCollectedPostListByToken(@ApiParam(name = "page", value = "查询页数", required = true)
                                               @PathVariable Integer page, @ApiParam(name = "limit", value = "查询数量", required = true)
                                               @PathVariable Integer limit, HttpServletRequest request) {
        try {
            String userId = JwtUtils.getMemberIdByJwtToken(request);
            PageResult PageResult = commentPostService.getCollectedPostListByToken(userId, page, limit);
            return Results.ok().data("page", PageResult).message(MessageConstant.QUERY_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (Exception e) {
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.QUERY_POST_FAIL);
        }
    }

    @ApiOperation(value = "（带条件）分页查询点赞最多帖子")
    @PostMapping("getPostListByCommentQueryVoAndTokenOrderByLike/{page}/{limit}")
    public Results getPostListByCommentQueryVoAndTokenOrderByLike(@ApiParam(name = "page", value = "查询页数", required = true)
                                                                  @PathVariable Integer page, @ApiParam(name = "limit", value = "查询数量", required = true)
                                                                  @PathVariable Integer limit, @ApiParam(name = "queryVo", value = "查询条件", required = false) @RequestBody CommentQueryVo queryVo, HttpServletRequest request) {
        try {
            String userId = JwtUtils.getMemberIdByJwtToken(request);
            PageResult PageResult = commentPostService.getPostListByCommentQueryVoAndTokenOrderByLike(userId, page, limit, queryVo);
            return Results.ok().data("page", PageResult).message(MessageConstant.QUERY_POST_SUCCESS);
        } catch (BaiYunException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaiYunException(ResultCode.ERROR, MessageConstant.QUERY_POST_FAIL);
        }
    }

    @ApiOperation("获取综合排名前十帖子")
    @GetMapping("getPostByScore")
    public Results getPostByScore() {
        // 查询 Redis 中的排名前十的帖子（按热度分数）
        Set<String> postIds = redisTemplate.opsForZSet().reverseRange("post_score", 0, 9);

        // 构建 MongoDB 查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").in(postIds));
        query.addCriteria(Criteria.where("isDeleted").is(false));

        // 查询所有符合条件的帖子
        List<CommentPost> commentPosts = mongoTemplate.find(query, CommentPost.class);

        // 将 MongoDB 查询结果按照 Redis 中的顺序进行排序
        Map<String, CommentPost> postMap = new HashMap<>();
        for (CommentPost post : commentPosts) {
            post.setScore(redisTemplate.opsForZSet().score("post_score", post.getId()));
            postMap.put(post.getId(), post);
        }
        // 根据 Redis 中的顺序重新排序
        List<CommentPost> sortedPosts = new ArrayList<>();
        for (String postId : postIds) {
            if (postMap.containsKey(postId)) {
                sortedPosts.add(postMap.get(postId));
            }
        }
        // 返回结果
        return Results.ok().data("list", sortedPosts).message(MessageConstant.QUERY_POST_SUCCESS);
    }
}

